import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:medito/services/network/download_service.dart';
import 'package:path_provider/path_provider.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'downloader_repository.g.dart';

abstract class DownloaderRepository {
  Future<void> downloadFile(
    String url, {
    required String fileName,
    void Function(int, int)? onReceiveProgress,
  });

  Future<String?> getDownloadedFile(String fileName);

  Future<void> deleteDownloadedFile(String fileName);

  Future<bool> isFileDownloaded(String name);
}

class DownloaderRepositoryImpl extends DownloaderRepository {
  final DownloadService _downloadService;
  final Ref ref;

  DownloaderRepositoryImpl({required this.ref})
      : _downloadService = DownloadService();

  @override
  Future<bool> isFileDownloaded(String name) async {
    var file = await getApplicationDocumentsDirectory();
    var savePath = '${file.path}/$name';

    return await File(savePath).exists();
  }

  @override
  Future<void> downloadFile(
    String url, {
    required String fileName,
    void Function(int, int)? onReceiveProgress,
  }) async {
    var file = await getApplicationDocumentsDirectory();
    var savePath = '${file.path}/$fileName';
    var isExists = await File(savePath).exists();

    if (!isExists) {
      await _downloadService.downloadFile(
        url,
        savePath,
        onProgress: onReceiveProgress,
      );
    }
  }

  @override
  Future<void> deleteDownloadedFile(String fileName) async {
    var file = await getApplicationDocumentsDirectory();
    var savePath = '${file.path}/$fileName';
    var filePath = File(savePath);
    var checkIsExists = await filePath.exists();
    if (checkIsExists) {
      await filePath.delete();
    }
  }

  @override
  Future<String?> getDownloadedFile(String fileName) async {
    if (kIsWeb) return null;
    var file = await getApplicationDocumentsDirectory();
    var savePath = '${file.path}/$fileName';
    var filePath = File(savePath);

    return await filePath.exists() ? filePath.path : null;
  }
}

@riverpod
DownloaderRepository downloaderRepository(Ref ref) {
  return DownloaderRepositoryImpl(ref: ref);
}
